package juc.aqs;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/*
*
* 借用AbstractQueuedSynchronizer 实现一个简单的不可重入锁
* */
public class Test1 {
    private static int t;
    public static void main(String[] args) throws InterruptedException {
        MyLock lock = new MyLock();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) {
                lock.lock();
                lock.lock();//不可重入
                try {
                    t++;
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) {
                lock.lock();
                try {
                    t++;
                } finally {
                    lock.unlock();
                }
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(t);
    }
}
class MyLock implements Lock {

    MySync sync=new MySync();
    class MySync extends AbstractQueuedSynchronizer{
        @Override
        protected boolean tryAcquire(int arg) {
            //利用cas来保证加锁的原子性
            if(compareAndSetState(0,arg)){
                //加锁成功
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            setExclusiveOwnerThread(null);
            //state 是一个volatile变量 放在下边利用写屏障保证以上不发生指令重排 和 上边所有变量的可见性
            setState(arg);
            return true;
        }

        @Override
        protected boolean isHeldExclusively() {
            return getState()==1;
        }
        public Condition newCondition(){
            return new ConditionObject();
        }
    }
    @Override
    public void lock() {//获取锁 否则进入阻塞队列
       sync.acquire(1);
    }
    @Override
    public void lockInterruptibly() throws InterruptedException {//加锁可打断
        sync.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1,unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.release(0);
    }

    @Override
    public Condition newCondition() {
        return sync.newCondition();
    }
}
